package com.hjh.testdemo.ui.audio

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.widget.SeekBar
import androidx.activity.result.contract.ActivityResultContracts
import androidx.navigation.fragment.findNavController
import com.hjh.core.activity.BaseFragment
import com.hjh.testdemo.databinding.FragmentAudioPlayerBinding
import com.hjh.testdemo.framework.audio.AudioPlayer
import com.hjq.toast.Toaster

class AudioPlayerFragment : BaseFragment<FragmentAudioPlayerBinding>(),
    SeekBar.OnSeekBarChangeListener {

    private lateinit var audioPlayer: AudioPlayer
    private var progressHandler = Handler(Looper.getMainLooper())
    private var isUserSeeking = false

    private val audioPickerLauncher = registerForActivityResult(
        ActivityResultContracts.StartActivityForResult()
    ) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            val uri = result.data?.data
            // 处理选中的音频文件
            uri?.let {
                loadAudio(uri)
            } ?: run {
                showError("未选择音频文件")
            }
        }
    }

    override fun initView() {
        requestPermission(
            storage = true,
            audio = true,
            onGranted = {
                audioPlayer = AudioPlayer(requireContext())
                with(binding) {
                    btnSelectAudio.setOnClickListener { openAudioFilePicker() }
                    btnPlayPause.setOnClickListener { togglePlayback() }
                    seekBar.setOnSeekBarChangeListener(this@AudioPlayerFragment)
                }
            },
            onDenied = {
                findNavController().navigateUp()
            })
    }

    private fun openAudioFilePicker() {
        val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "audio/*"
        }
        audioPickerLauncher.launch(intent)
    }

    private fun loadAudio(uri: Uri) {
        audioPlayer.loadAudio(
            uri = uri,
            onPrepared = {
                binding.btnPlayPause.isEnabled = true
                binding.seekBar.max = audioPlayer.getDuration()
                updateTimeDisplay()
            },
            onError = { showError(it) }
        )
    }

    private fun togglePlayback() {
        if (audioPlayer.isPlaying()) {
            audioPlayer.pause()
            stopProgressUpdate()
        } else {
            audioPlayer.play(
                onStart = { startProgressUpdate() },
                onError = { showError(it) }
            )
        }
        updatePlayButtonState()
    }

    private fun startProgressUpdate() {
        progressHandler.postDelayed(updateProgress, 100)
    }

    private fun stopProgressUpdate() {
        progressHandler.removeCallbacks(updateProgress)
    }

    private val updateProgress = object : Runnable {
        override fun run() {
            if (!isUserSeeking) {
                binding.seekBar.progress = audioPlayer.getCurrentPosition()
                updateTimeDisplay()
            }
            progressHandler.postDelayed(this, 100)
        }
    }

    @SuppressLint("SetTextI18n")
    private fun updateTimeDisplay() {
        val current = audioPlayer.getCurrentPosition().toTimeString()
        val total = audioPlayer.getDuration().toTimeString()
        binding.tvTime.text = "$current / $total"
    }

    @SuppressLint("DefaultLocale")
    private fun Int.toTimeString(): String {
        val minutes = (this / 1000) / 60
        val seconds = (this / 1000) % 60
        return String.format("%02d:%02d", minutes, seconds)
    }

    override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
        if (fromUser) audioPlayer.seekTo(progress)
    }

    override fun onStartTrackingTouch(seekBar: SeekBar?) {
        isUserSeeking = true
    }

    override fun onStopTrackingTouch(seekBar: SeekBar?) {
        isUserSeeking = false
    }

    override fun onDestroyView() {
        super.onDestroyView()
        audioPlayer.release()
        progressHandler.removeCallbacksAndMessages(null)
    }

    private fun updatePlayButtonState() {
        binding.btnPlayPause.text = if (audioPlayer.isPlaying()) "暂停" else "播放"
    }

    private fun showError(message: String) {
        Toaster.show(message)
    }
}